export default defineNuxtPlugin((nuxtApp) => {
  // 扩展 HTMLElement 类型
  interface ExtendedHTMLElement extends HTMLElement {
    _hideOnKeyboardCleanup?: () => void
  }
  nuxtApp.vueApp.directive('hide-on-keyboard', {
    mounted(el: ExtendedHTMLElement, binding: any) {
      // 解析指令参数
      const options = binding.value || {}
      const {
        threshold = 100, // 触发隐藏的高度阈值
        delay = 100, // 显示延迟时间
        animation = false, // 是否使用动画
        className = 'keyboard-hidden', // 自定义隐藏时的CSS类名
      } = options

      // 获取初始视口高度
      const getInitialHeight = () => window.visualViewport?.height || window.innerHeight

      let initialHeight = getInitialHeight()
      let isHidden = false
      let resizeTimeout: NodeJS.Timeout | null = null

      // 隐藏元素
      const hideElement = () => {
        if (isHidden)
          return

        if (animation) {
          el.style.transition = 'opacity 0.2s ease-out'
          el.style.opacity = '0'
          setTimeout(() => {
            el.style.display = 'none'
            el.classList.add(className)
          }, 200)
        } else {
          el.style.display = 'none'
          el.classList.add(className)
        }

        isHidden = true
      }

      // 显示元素
      const showElement = () => {
        if (!isHidden)
          return

        el.style.display = ''
        el.classList.remove(className)

        if (animation) {
          el.style.opacity = '0'
          requestAnimationFrame(() => {
            el.style.opacity = '1'
          })
        }

        isHidden = false
      }

      // 处理视口变化
      const handleViewportChange = () => {
        if (!window.visualViewport)
          return

        const currentHeight = window.visualViewport.height
        const heightDifference = initialHeight - currentHeight

        // 清除之前的定时器
        if (resizeTimeout) {
          clearTimeout(resizeTimeout)
        }

        // 如果高度差大于阈值，认为是键盘弹出
        if (heightDifference > threshold) {
          hideElement()
        } else {
          // 键盘收起，延迟显示避免闪烁
          resizeTimeout = setTimeout(() => {
            showElement()
          }, delay)
        }
      }

      // 处理窗口大小变化（兼容性处理）
      const handleResize = () => {
        // 重新获取初始高度
        initialHeight = getInitialHeight()
      }

      // 监听视口变化
      if (window.visualViewport) {
        window.visualViewport.addEventListener('resize', handleViewportChange)
      } else {
        // 降级方案：使用 window resize 事件
        window.addEventListener('resize', handleResize)
        // 使用定时器检测高度变化
        let lastHeight = window.innerHeight
        setInterval(() => {
          const currentHeight = window.innerHeight
          if (Math.abs(currentHeight - lastHeight) > threshold) {
            if (currentHeight < lastHeight) {
              hideElement()
            } else {
              showElement()
            }
            lastHeight = currentHeight
          }
        }, 100)
      }

      // 存储清理函数
      el._hideOnKeyboardCleanup = () => {
        if (window.visualViewport) {
          window.visualViewport.removeEventListener(
            'resize',
            handleViewportChange,
          )
        } else {
          window.removeEventListener('resize', handleResize)
        }
        if (resizeTimeout) {
          clearTimeout(resizeTimeout)
        }
      }
    },

    unmounted(el: ExtendedHTMLElement) {
      // 清理事件监听器
      if (el._hideOnKeyboardCleanup) {
        el._hideOnKeyboardCleanup()
      }
    },
  })
})
